package com.opencee.cloud.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.opencee.boot.db.mybatis.service.impl.SupperServiceImpl;
import com.opencee.cloud.base.constants.BaseConstants;
import com.opencee.cloud.base.entity.BaseSystemEntity;
import com.opencee.cloud.base.mapper.BaseSystemMapper;
import com.opencee.cloud.base.service.IBaseApplicationService;
import com.opencee.cloud.base.service.IBaseSystemService;
import com.opencee.cloud.base.vo.BaseApplicationDetailsVO;
import com.opencee.cloud.base.vo.BaseApplicationResultVO;
import com.opencee.common.exception.BaseFailException;
import com.opencee.common.security.SecurityClient;
import com.opencee.common.utils.RedisTemplateUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 系统信息 服务实现类
 * </p>
 *
 * @author liuyadu
 * @since 2021-04-16
 */
@Service
public class BaseSystemServiceImpl extends SupperServiceImpl<BaseSystemMapper, BaseSystemEntity> implements IBaseSystemService {
    @Autowired
    private RedisTemplateUtil redisTemplateUtil;
    @Autowired
    private IBaseApplicationService baseApplicationService;

    /**
     * 检测系统ID是否存在
     *
     * @param sid
     * @return
     */
    @Override
    public boolean exists(String sid) {
        if (StringUtils.isBlank(sid)) {
            throw new BaseFailException("系统ID不能为空!");
        }
        QueryWrapper<BaseSystemEntity> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseSystemEntity::getSid, sid);
        return super.count(queryWrapper) > 0;
    }

    /**
     * 根据主键查询
     *
     * @param id
     * @return
     */
    @Override
    public BaseSystemEntity getById(Serializable id) {
        String key = BaseConstants.CACHE_SYSTEM_ID + id;
        if (redisTemplateUtil.hasKey(key)) {
            return (BaseSystemEntity) redisTemplateUtil.get(key);
        }
        BaseSystemEntity entity = super.getById(id);
        if (entity != null) {
            redisTemplateUtil.set(key, entity);
        } else {
            redisTemplateUtil.set(key, entity, 1, TimeUnit.MINUTES);
        }
        return entity;
    }

    /**
     * 保存
     *
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean save(BaseSystemEntity entity) {
        if (exists(entity.getSid())) {
            throw new BaseFailException(String.format("系统ID(%s)已存在!", entity.getSid()));
        }
        if (entity.getStatus() == null) {
            entity.setStatus(1);
        }
        if (entity.getSsoEnabled() == null) {
            entity.setSsoEnabled(true);
        }
        Assert.hasText(entity.getHost(), "系统主页地址,不能为空");

        String grantTypes = "";
        if (entity.getSsoEnabled()) {
            Assert.hasText(entity.getSsoRedirectUri(), "开启SSO登录,重定向地址不能为空");
            grantTypes = "authorization_code,refresh_token,implicit";
        }

        // 应用信息
        SecurityClient client = new SecurityClient("", "", "user_info", grantTypes, "", entity.getSsoRedirectUri());
        client.setAutoApproveScopes(client.getScope());
        BaseApplicationDetailsVO app = new BaseApplicationDetailsVO();
        app.setAppName(entity.getName());
        app.setStatus(entity.getStatus());
        app.setDeveloperType(0);
        app.setType("pc");
        app.setHost(entity.getHost());
        app.setRemark(entity.getRemark());
        app.setClient(client);
        BaseApplicationResultVO result = baseApplicationService.saveApp(app);
        entity.setAppId(result.getAppId());
        entity.setDeleted(0);
        entity.setCreateTime(new Date());
        entity.setUpdateTime(entity.getCreateTime());
        boolean flag = super.save(entity);
        if (flag) {
            // 设置缓存
            String idKey = BaseConstants.CACHE_SYSTEM_ID + entity.getId();
            redisTemplateUtil.set(idKey, entity);
        }
        return flag;
    }

    /**
     * 修改
     *
     * @param entity
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateById(BaseSystemEntity entity) {
        BaseSystemEntity saved = getById(entity.getId());
        if (saved == null) {
            throw new BaseFailException(String.format("系统不存在!"));
        }
        // 系统编码不允许修改
        entity.setSid(null);
        entity.setUpdateTime(new Date());
        if (entity.getStatus() == null) {
            entity.setStatus(1);
        }
        if (entity.getSsoEnabled() == null) {
            entity.setSsoEnabled(true);
        }
        Assert.hasText(entity.getHost(), "系统主页地址,不能为空");

        String grantTypes = "";
        if (entity.getSsoEnabled()) {
            Assert.hasText(entity.getSsoRedirectUri(), "开启SSO登录,重定向地址不能为空");
            grantTypes = "authorization_code,refresh_token,implicit";
        }

        // 应用信息
        BaseApplicationDetailsVO app = new BaseApplicationDetailsVO();
        app.setAppId(saved.getAppId());
        app.setAppName(entity.getName());
        app.setStatus(entity.getStatus());
        app.setType("pc");
        app.setDeveloperType(0);
        app.setHost(entity.getHost());
        app.setRemark(entity.getRemark());

        baseApplicationService.updateApp(app);
        boolean flag = super.updateById(entity);
        if (flag) {
            // 移除缓存
            String idKey = BaseConstants.CACHE_SYSTEM_ID + saved.getId();
            String idKey2 = BaseConstants.CACHE_SYSTEM_ID + saved.getAppId();
            redisTemplateUtil.del(idKey, idKey2);
        }
        return flag;
    }

    /**
     * 根据系统ID查询系统
     *
     * @param sid
     * @return
     */
    @Override
    public BaseSystemEntity getBySid(String sid) {
        String key = BaseConstants.CACHE_SYSTEM_ID + sid;
        if (redisTemplateUtil.hasKey(key)) {
            return (BaseSystemEntity) redisTemplateUtil.get(key);
        }
        QueryWrapper<BaseSystemEntity> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseSystemEntity::getSid, sid);
        BaseSystemEntity entity = super.getOne(queryWrapper);
        if (entity != null) {
            String key2 = BaseConstants.CACHE_SYSTEM_APP_ID + entity.getAppId();
            redisTemplateUtil.set(key, entity);
            redisTemplateUtil.set(key2, entity);
        } else {
            redisTemplateUtil.set(key, entity, 1, TimeUnit.MINUTES);
        }
        return entity;
    }

    /**
     * 根据appId查询系统
     *
     * @param appId
     * @return
     */
    @Override
    public BaseSystemEntity getByAppId(String appId) {
        String key = BaseConstants.CACHE_SYSTEM_APP_ID + appId;
        if (redisTemplateUtil.hasKey(key)) {
            return (BaseSystemEntity) redisTemplateUtil.get(key);
        }
        QueryWrapper<BaseSystemEntity> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(BaseSystemEntity::getAppId, appId);
        BaseSystemEntity entity = super.getOne(queryWrapper);
        if (entity != null) {
            String key2 = BaseConstants.CACHE_SYSTEM_ID + entity.getSid();
            redisTemplateUtil.set(key, entity);
            redisTemplateUtil.set(key2, entity);
        } else {
            redisTemplateUtil.set(key, entity, 1, TimeUnit.MINUTES);
        }
        return entity;
    }

    /**
     * 根据名称或ID模糊查询
     *
     * @param keyword
     * @return
     */
    @Override
    public List<BaseSystemEntity> listByKeyword(String keyword) {
        QueryWrapper<BaseSystemEntity> queryWrapper = new QueryWrapper();
        queryWrapper.lambda()
                .like(BaseSystemEntity::getName, keyword)
                .or()
                .like(BaseSystemEntity::getSid, keyword);
        return super.list(queryWrapper);
    }

    /**
     * 批量code查询
     *
     * @param sids
     * @return
     */
    @Override
    public List<BaseSystemEntity> listBySid(Set<String> sids) {
        if (sids.isEmpty()) {
            return Collections.EMPTY_LIST;
        }
        QueryWrapper<BaseSystemEntity> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().in(BaseSystemEntity::getSid, sids);
        List<BaseSystemEntity> list = super.list(queryWrapper);
        return list;
    }


    /**
     * 批量code查询转map
     *
     * @param sids
     * @return
     */
    @Override
    public Map<Long, BaseSystemEntity> mapBySids(Set<String> sids) {
        Map<Long, BaseSystemEntity> map = new HashMap<>(8);
        if (sids.isEmpty()) {
            return map;
        }
        List<BaseSystemEntity> list = listByIds(sids);
        list.forEach(t -> {
            map.put(t.getId(), t);
        });
        return map;
    }


    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeById(Serializable id) {
        BaseSystemEntity saved = getById(id);
        if (saved == null) {
            return false;
        }
        boolean flag = super.removeById(id);
        if (flag) {
            baseApplicationService.removeById(saved.getAppId());
            // 移除缓存
            String idKey = BaseConstants.CACHE_SYSTEM_ID + saved.getId();
            String idKey2 = BaseConstants.CACHE_SYSTEM_APP_ID + saved.getId();
            redisTemplateUtil.del(idKey, idKey2);
        }
        return flag;
    }
}
